package com.ssamkj.rssbot.util;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;
import org.junit.Test;

public class DateStringParser {
	private static final Logger logger = Logger.getLogger(DateStringParser.class);

	protected enum DATEFORMAT {
		FORMAT1("[A-z]{3}{space}\\d{2}{space}\\d{4}"), FORMAT2(
				"\\d{2}{space}[A-z]{3}{space}\\d{4}"), FORMAT3(
				"\\d{4}{space}\\d{2}{space}\\d{2}");

		private String pattern;

		DATEFORMAT(String pattern) {
			this.pattern = pattern;
		}

		public String getPattern() {
			return this.pattern;
		}
	}

	protected enum SPACE {
		SPACE1(" "), SPACE2("-"), SPACE3(".");
		private String space;

		SPACE(String space) {
			this.space = space;
		}

		public String getSpace() {
			return this.space;
		}
	}

	// 1 시간 빼기.
	protected String getTime(String rawDateString) {
		String timePattern = "[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}";
		Pattern p = Pattern.compile(timePattern);
		Matcher m = p.matcher(rawDateString);

		if (m.find())
			return m.group();

		return null;
	}

	// 2. 요일 제거
	protected String StringReplace(String str) {
		// String match = "[^\uAC00-\uD7A3xfe0-9a-zA-Z\\s]";
		String match = "(Mon|Tue|Wed|Thu|Fri|Sat|Sun)";
		Pattern p = Pattern.compile(match);
		Matcher m = p.matcher(str);
		if (m.find()) {
//			logger.debug("============== " + m.group());
			str = str.replaceAll(m.group(), " ");
		}
		str = str.replaceAll(",", " ");
		str = str.replaceAll("   ", " ");
		str = str.replaceAll("  ", " ");

		return str;
	}

	public synchronized Calendar dateStringParserToCalendar(String input) {
		if(input.trim().length()==0) return null;
		
		logger.debug(input);
		Calendar cal = Calendar.getInstance();

		if (isOnlyNumber(input)) {
			cal.set(Calendar.YEAR, Integer.parseInt(input.substring(0, 4)));
			cal.set(Calendar.MONTH, Integer.parseInt(input.substring(4, 6)) - 1);
			cal.set(Calendar.DATE, Integer.parseInt(input.substring(6, 8)));
			cal.set(Calendar.HOUR_OF_DAY,
					Integer.parseInt(input.substring(8, 10)));
			cal.set(Calendar.MINUTE, Integer.parseInt(input.substring(10, 12)));
			cal.set(Calendar.SECOND, Integer.parseInt(input.substring(12, 14)));
			return cal;
		}

		String timeString = getTime(input);

		if (timeString != null) {
			input = input.replaceAll(timeString, "");
		}
		// logger.debug("시간 제거 : "+input);
		input = StringReplace(input); // 요일제거
		// logger.debug("요일 제거 : "+input);
		String dateString = getDate(input);
		if (dateString != null) {
			input = input.replaceAll(dateString, "");
		}
		try {
			setTime(cal, timeString);
			setDate(cal, dateString);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		// logger.debug("날짜 제거 : "+input);

		// 오전/오후 제거
		input = input.trim();
		if (input.length() > 0) {
//			logger.debug("남은 항목 : " + input);
			if (input.equals("오후")) {
				cal.set(Calendar.AM_PM, Calendar.PM);
				input = input.replace("오후", "");
			} else if (input.equals("오전")) {
				cal.set(Calendar.AM_PM, Calendar.AM);
				input = input.replace("오전", "");
			}
			if (input.equals("am")) {
				cal.set(Calendar.AM_PM, Calendar.AM);
				input = input.replace("am", "");
			} else if (input.equals("AM")) {
				cal.set(Calendar.AM_PM, Calendar.AM);
				input = input.replace("AM", "");
			} else if (input.equals("Am")) {
				cal.set(Calendar.AM_PM, Calendar.AM);
				input = input.replace("Am", "");
			} else if (input.equals("pm")) {
				cal.set(Calendar.AM_PM, Calendar.PM);
				input = input.replace("pm", "");
			} else if (input.equals("PM")) {
				cal.set(Calendar.AM_PM, Calendar.PM);
				input = input.replace("PM", "");
			} else if (input.equals("Pm")) {
				cal.set(Calendar.AM_PM, Calendar.PM);
				input = input.replace("Pm", "");
			}

		}

		input = input.trim();
		if (input.length() > 0) {
			cal.setTimeZone(TimeZone.getTimeZone(input));
		}
		return cal;
	}

	protected boolean isOnlyNumber(String input) {
		String onlyNumberPattern = "\\D";
		Pattern p;
		Matcher m;
		p = Pattern.compile(onlyNumberPattern);
		m = p.matcher(input);
		return !m.find();
	}

	protected void setTime(Calendar cal, String timeString) throws Exception {
		if(timeString==null || timeString.trim().length()==0) return;
		String[] timeArr = timeString.split(":");
		if (timeArr.length == 3) {
			cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeArr[0]));
			cal.set(Calendar.MINUTE, Integer.parseInt(timeArr[1]));
			cal.set(Calendar.SECOND, Integer.parseInt(timeArr[2]));
		} else {
			throw new Exception("시간이 이상해!!!");
		}

	}

	protected void setDate(Calendar cal, String dateString) throws Exception {
		if(dateString==null || dateString.trim().length()==0) return;
		
		String[] monthArr = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
				"Aug", "Sep", "Oct", "Nov", "Dec" };
		Pattern p;
		Matcher m;
		int month = -1;
		String year = "";
		String date = "";
//		logger.debug(" setDate start = " + dateString);
		for (int i = 0; i < monthArr.length; i++) {
			p = Pattern.compile(monthArr[i]);
			m = p.matcher(dateString);
			if (m.find()) {
//				logger.debug("============== " + m.group());

				month = i;
				dateString = dateString.replaceAll(m.group(), "");
			}
		}

		String yearPattern = "\\d{4}";
		p = Pattern.compile(yearPattern);
		m = p.matcher(dateString);
		if (m.find()) {
			dateString = dateString.replaceAll(m.group(), " ");
			year = m.group();
		}

		if (month == -1) {
			String monthPattern = "\\d{2}";
			p = Pattern.compile(monthPattern);
			m = p.matcher(dateString);
			if (m.find()) {
				dateString = dateString.replaceAll(m.group(0), " ");
				month = Integer.parseInt(m.group(0)) - 1;
			}
		}
		String dayPattern = "\\d{2}";
		p = Pattern.compile(dayPattern);
		m = p.matcher(dateString);
		if (m.find()) {
			dateString = dateString.replaceAll(m.group(0), " ");
			date = m.group(0);
		}

		// logger.debug("year = "+year+", numberOfMonth = "+month+", day = "+date+", left="+dateString);
		if (year.length() > 0 && month != -1 && date.length() > 0) {
			cal.set(Calendar.YEAR, Integer.parseInt(year));
			cal.set(Calendar.MONTH, month);
			cal.set(Calendar.DATE, Integer.parseInt(date));
		} else {
			logger.debug("year = " + year + ", numberOfMonth = " + month
					+ ", day = " + date + ", left=" + dateString);
			throw new Exception("못 찾았어!! 뭔가가 잘못됐어.");
		}
	}

	protected String getDate(String input) {

		String pattern;
		boolean found = false;
		for (DATEFORMAT d : DATEFORMAT.values()) {
			if (found)
				break;
			pattern = d.getPattern();
			for (SPACE s : SPACE.values()) {
				if (found)
					break;
				String pattern2 = pattern.replace("{space}", s.getSpace());
				Pattern p = Pattern.compile(pattern2);
				Matcher m = p.matcher(input);
				if (m.find()) {
					return m.group();
				}
			}
		}
		return null;
	}

	@Test
	public void main() {
		System.out.println(System.getProperty("user.dir"));
		String log4jConfigFile = System.getProperty("user.dir")+File.separator+"resource"+File.separator+"log4j"
                + File.separator + "log4j.xml";
        DOMConfigurator.configure(log4jConfigFile);
        
        
		SimpleDateFormat format = new java.text.SimpleDateFormat(
				"yyyy년MM월dd일 EEE HH시mm분ss초");

		logger.debug(format.format(dateStringParserToCalendar(
				"Mon, 15 Apr 2013 11:14:53 GMT").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"2013.04.23 16:30:06 +0900").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"2013-04-24 오후 6:17:00").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"Mon, 15 Apr 2013 11:14:53").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"20130425112536").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"Thu, 25 Apr 2013 14:51:15 +0900").getTime()));
//		logger.debug(format.format(dateStringParserToCalendar(
//				" ").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"Thu, 25 Apr 2013 15:51:10 +0900").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"N1001754387").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"Thu, 25 Apr 2013 16:05:34 +0900").getTime()));

		logger.debug(format.format(dateStringParserToCalendar(
				"2013.04.25 15:30:03").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"Mon, 15 Apr 2013 11:14:53 GMT").getTime()));
		logger.debug(format.format(dateStringParserToCalendar(
				"Thu, 25 Apr 2013 16:05:36 +0900").getTime()));
//		logger.debug(format.format(dateStringParserToCalendar(
//				"").getTime()));
		
	}
}
